package com.ruoyi.store.service.impl;

import com.ruoyi.caigou.api.RemoteBuyBackOrderService;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.finance.api.RemoteReciveReqService;
import com.ruoyi.store.domain.StockTransfer;
import com.ruoyi.store.domain.StockTransferDetail;
import com.ruoyi.store.dto.StockOutSto;
import com.ruoyi.store.mapper.*;
import com.ruoyi.store.service.IStockOutService;
import com.ruoyi.system.api.constants.BuyBackOrderConstants;
import com.ruoyi.system.api.domain.caigou.BuyBackOrder;
import com.ruoyi.system.api.domain.caigou.BuyBackOrderDetail;
import com.ruoyi.system.api.domain.finance.ReciveReq;
import com.ruoyi.system.api.domain.store.StockOut;
import com.ruoyi.system.api.domain.store.StockOutDetail;
import com.ruoyi.system.api.domain.store.WarehouseGoods;
import com.ruoyi.xiaoshou.api.RemoteSaleOrderDetailService;
import com.ruoyi.xiaoshou.api.RemoteSaleOrderService;
import com.ruoyi.xiaoshou.domain.SaleOrder;
import com.ruoyi.xiaoshou.domain.SaleOrderDetail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 出库记录Service业务层处理
 *
 * @author ruoyi
 * @date 2024-10-31
 */
@Service
@Transactional
@Slf4j
public class StockOutServiceImpl implements IStockOutService {
    @Autowired
    private StockOutMapper stockOutMapper;

    @Autowired
    private SaleOrderMapper saleOrderMapper;

    @Autowired
    private SaleOrderDetailMapper saleOrderDetailMapper;

    @Autowired
    private StockOutDetailMapper stockOutDetailMapper;

    @Autowired
    private WarehouseGoodsMapper warehouseGoodsMapper;

    @Autowired
    private RemoteSaleOrderService remoteSaleOrderService;

    @Autowired
    private RemoteSaleOrderDetailService remoteSaleOrderDetailService;

    @Autowired
    private StockTransferMapper stockTransferMapper;

    @Autowired
    private StockTransferDetailMapper stockTransferDetailMapper;
    @Autowired
    private RemoteBuyBackOrderService remoteBuyBackOrderService;
    @Autowired
    private RemoteReciveReqService remoteReciveReqService;

    /**
     * 查询出库记录
     *
     * @param id 出库记录主键
     * @return 出库记录
     */
    @Override
    public StockOut selectStockOutById(Integer id) {
        return stockOutMapper.selectStockOutById(id);
    }

    @Override
    public String outStock(StockOutSto stockOutSto) {
        int totalStock = 0;
        int stockCount = 0;
        int stockOutId = 0;
        for (StockOutDetail stockOutDetail : stockOutSto.getStockOutDetails()) {
            totalStock += stockOutDetail.getNumByOutStock();
            stockCount += stockOutDetail.getNum() - stockOutDetail.getStockOutNumber();
            stockOutId = stockOutDetail.getStockOutId();
            WarehouseGoods warehouseGoods = new WarehouseGoods();
            warehouseGoods.setGoodsId(stockOutDetail.getGoodsId());
            warehouseGoods.setHouseId(stockOutSto.getHouseId());
            //判断库存
            int stock = warehouseGoodsMapper.getStockByProId(warehouseGoods);
            log.info("StockOutServiceImpl outStock    stock:" + stock + stockOutDetail);
            if (stockOutDetail.getNumByOutStock() > stock) {
                throw new ServiceException
                        ("商品：" + stockOutDetail.getProName() + "库存不足，" +
                                "当前库存" + stock + "出库数量：" + stockOutDetail.getNumByOutStock());
            }
            //修改出库需求详情
            stockOutDetail.setModifyBy(SecurityUtils.getUsername());
            int count = stockOutDetailMapper.updDetail(stockOutDetail);
            if (count < 0) {
                throw new ServiceException("系统错误，操作失败");
            }
            //减少库存
            warehouseGoods.setStock(stock - stockOutDetail.getNumByOutStock());
            warehouseGoods.setModifyBy(SecurityUtils.getUsername());
            int count1 = warehouseGoodsMapper.updStock(warehouseGoods);
            if (count1 < 1) {
                throw new ServiceException("系统错误，操作失败");
            }
        }
        //修改需求单实际出库数量
        StockOut stockOut = new StockOut();
        if (totalStock != 0) {
            stockOut.setId(stockOutId);
            stockOut.setModifyBy(SecurityUtils.getUsername());
            stockOut.setTotalOutNumber(totalStock);
            stockOut.setStockStatus(1);
            if (totalStock == stockCount) {
                stockOut.setStockStatus(2);
            }
            int count2 = stockOutMapper.updStatus(stockOut);
            if (count2 < 1) {
                throw new ServiceException("系统错误，操作失败");
            }
        }
        stockOut = stockOutMapper.selectStockOutById(stockOutId);
        BigDecimal money = new BigDecimal(0);
        ReciveReq reciveReq = new ReciveReq();
        switch (stockOut.getInventoryTypeId()) {
            case 2:
                //获取出库需求单数据
                StockOut stockOut1 = stockOutMapper.selectStockOutById(stockOut.getId());
                //更新销售订单出库数据
                SaleOrder saleOrder = new SaleOrder();
                saleOrder.setUpdateBy(SecurityUtils.getUsername());
                saleOrder.setStockStatus(stockOut1.getStockStatus());
                saleOrder.setOutStockNumber(totalStock);
                saleOrder.setCode(stockOut1.getOrderCode());
                int count4 = remoteSaleOrderService.edit(saleOrder, SecurityConstants.INNER);
                //获取订单id
                SaleOrder saleOrder1 = saleOrderMapper.getOrderId(stockOut1.getOrderCode());
                //更新销售订单详情数据
                //生成销售应收单
                //应收单编号
                reciveReq.setOrderCode("CWYS" + System.currentTimeMillis());
                //单据日期
                reciveReq.setOrderDate(new Date());
                //客户
                reciveReq.setCustomerId(saleOrder1.getCusId());
                //应收单类型为销售应收
                reciveReq.setPaymentType(101);
                //单据状态为已审批
                reciveReq.setOrderStatus(3);
                //设置业务员id
                reciveReq.setOrderUserId(Math.toIntExact(SecurityUtils.getUserId()));
                //设置销售单号
                reciveReq.setSrcOrderCode(stockOut1.getStockOutCode());
                //设置审核未通过状态
                reciveReq.setApprovalResult(BuyBackOrderConstants.APPROVAL_APPROVED);
                //设置未已生效
                reciveReq.setIsEffect(1);
                //设置生效日期
                reciveReq.setEffectDate(new Date());
                //设置生效日期
                reciveReq.setEffectDate(new Date());
                for (StockOutDetail stockOutDetail : stockOutSto.getStockOutDetails()) {
                    SaleOrderDetail saleOrderDetail = new SaleOrderDetail();
                    saleOrderDetail.setUpdateBy(SecurityUtils.getUsername());
                    saleOrderDetail.setOrderId(saleOrder1.getId());
                    saleOrderDetail.setOutStock(stockOutDetail.getNumByOutStock());
                    saleOrderDetail.setProId(stockOutDetail.getGoodsId());
                    remoteSaleOrderDetailService.update(saleOrderDetail, SecurityConstants.INNER);
                    //获取销售订单详情数据
                    saleOrderDetail = remoteSaleOrderDetailService.getSaleOrderDetailByProIdAndOrderId(saleOrderDetail);
                    //获取当前详情出库金额
                    BigDecimal result = saleOrderDetail.getPrice().multiply(BigDecimal.valueOf(stockOutDetail.getNumByOutStock()));
                    //累加当前订单出库总价
                    money = money.add(result);
                }
                reciveReq.setMoney(money);
                AjaxResult add = remoteReciveReqService.add(reciveReq);
                break;
            case 3:
                //获取出库需求单数据
                stockOut1 = stockOutMapper.selectStockOutById(stockOut.getId());
                //更新采购退货订单出库数据
                BuyBackOrder buyBackOrder = remoteBuyBackOrderService.getInfoByBuyBackOrderCode(stockOut1.getOrderCode()).getData();
                buyBackOrder.setModifyBy(SecurityUtils.getUsername());
                if (buyBackOrder.getStockStatus() == 1) {
                    buyBackOrder.setStockStatus(2);
                }
                buyBackOrder.setStockStatus(stockOut1.getStockStatus() + 1);
                buyBackOrder.setRealOutStock(buyBackOrder.getRealOutStock() + totalStock);
                if (buyBackOrder.getAllOutStock() == buyBackOrder.getRealOutStock()) {
                    buyBackOrder.setStockStatus(3);
                }
                buyBackOrder.setBuyBackOrderCode(stockOut1.getOrderCode());
                AjaxResult ajaxResult = remoteBuyBackOrderService.updateBuyBackOrderByOrderCode(buyBackOrder);
                //添加应收单
                //应收单编号
                reciveReq.setOrderCode("CWYS" + System.currentTimeMillis());
                //单据日期
                reciveReq.setOrderDate(new Date());
                //应收单类型为采购退货应收
                reciveReq.setPaymentType(102);
                //单据状态为已审批
                reciveReq.setOrderStatus(3);
                //设置业务员id
                reciveReq.setOrderUserId(Math.toIntExact(SecurityUtils.getUserId()));
                //设置采购退货供应商
                reciveReq.setSupplierId(buyBackOrder.getSupplierId());
                //设置采购退货单号
                reciveReq.setSrcOrderCode(stockOut1.getStockOutCode());
                //设置审核未通过状态
                reciveReq.setApprovalResult(BuyBackOrderConstants.APPROVAL_APPROVED);
                //设置未已生效
                reciveReq.setIsEffect(1);
                //设置生效日期
                reciveReq.setEffectDate(new Date());
                //更新采购退货订单详情数据
                for (StockOutDetail stockOutDetail : stockOutSto.getStockOutDetails()) {
                    BuyBackOrderDetail buyBackOrderDetail = new BuyBackOrderDetail();
                    buyBackOrderDetail.setModifyBy(SecurityUtils.getUsername());
                    buyBackOrderDetail.setBuyBackOrderId(buyBackOrder.getId());
                    buyBackOrderDetail.setOutStock(stockOutDetail.getNumByOutStock());
                    buyBackOrderDetail.setGoodsId(stockOutDetail.getGoodsId());
                    buyBackOrderDetail.setRealOutStock(stockOutDetail.getStockOutNumber());
                    remoteBuyBackOrderService.updateBuyBackOrderDetailByOrderIdGoodsId(buyBackOrderDetail);
                    R<BuyBackOrderDetail> buyBackOrderDetailByOrderIdGoodsId = remoteBuyBackOrderService.getBuyBackOrderDetailByOrderIdGoodsId(buyBackOrderDetail);
                    buyBackOrderDetail = buyBackOrderDetailByOrderIdGoodsId.getData();
                    BigDecimal res = buyBackOrderDetail.getCost().multiply(BigDecimal.valueOf(stockOutDetail.getNumByOutStock()));
                    money = money.add(res);
                }
                reciveReq.setMoney(money);
                add = remoteReciveReqService.add(reciveReq);
                break;
            case 5:
                //获取出库需求单数据
                stockOut1 = stockOutMapper.selectStockOutById(stockOut.getId());
                //更新调拨单状态
                StockTransfer stockTransfer = new StockTransfer();
                stockTransfer.setUpdateBy(SecurityUtils.getUsername());
                stockTransfer.setStatus(stockOut1.getStockStatus());
                int id = stockTransferMapper.getOrderIdByCode(stockOut1.getOrderCode());
                stockTransfer.setId(id);
                int num = stockTransferMapper.updateStockTransfer(stockTransfer);
                if (num < 0) {
                    throw new ServiceException("系统错误，操作失败");
                }
                break;
        }
        //生成应收单


        return "出库成功";
    }

    /**
     * 查询出库记录列表
     *
     * @param stockOut 出库记录
     * @return 出库记录
     */
    @Override
    public List<StockOut> selectStockOutList(StockOut stockOut) {
        return stockOutMapper.selectStockOutList(stockOut);
    }

    @Override
    public List<StockOut> getStockTranList(StockOut stockOut) {
        return stockOutMapper.getStockTranList(stockOut);
    }

    /**
     * 添加出库需求单
     *
     * @param id
     * @return
     */
    @Override
    public String addOutStock(int id) {
        //查询销售订单
        SaleOrder saleOrder = saleOrderMapper.selectSaleOrderById(id);
        StockOut stockOut = new StockOut();
        //给需求单对象赋值
        String stockOutCode = "CKXQ" + System.currentTimeMillis() + "";
        stockOut.setStockOutCode(stockOutCode);
        stockOut.setOrderCode(saleOrder.getCode());
        stockOut.setCreateBy(SecurityUtils.getUsername());
        stockOut.setInventoryTypeId(2);
        stockOut.setStockNum(saleOrder.getOutStockNum());
        stockOut.setCusName(saleOrder.getCusName());
        //添加需求单
        int count = stockOutMapper.insertStockOut(stockOut);
        if (count < 0) {
            throw new ServiceException("系统错误 添加失败");
        }
        saleOrder.setIsStockOut(1);
        count = remoteSaleOrderService.edit(saleOrder, SecurityConstants.INNER);
        stockOut = stockOutMapper.getStockOutByCode(stockOutCode);
        List<SaleOrderDetail> list = saleOrderDetailMapper.getList(id);
        for (SaleOrderDetail saleOrderDetail : list) {
            StockOutDetail stockOutDetail = new StockOutDetail();
            stockOutDetail.setStockOutId(stockOut.getId());
            stockOutDetail.setGoodsId(saleOrderDetail.getProId());
            stockOutDetail.setNum(saleOrderDetail.getNumber());
            stockOutDetail.setCreateBy(SecurityUtils.getUsername());
            int count1 = stockOutDetailMapper.addDetail(stockOutDetail);
            if (count1 < 0) {
                throw new ServiceException("系统错误 添加失败");
            }
        }
        return "添加成功";
    }

    @Override
    public List<StockOut> getUseList(StockOut stockOut) {
        log.info("StockOutServiceImpl getUseList params:{}", stockOut);
        List<StockOut> stockOuts = stockOutMapper.getUseList(stockOut);
        return stockOuts;
    }

    /**
     * 添加调拨出库需求
     *
     * @param id
     * @return
     */
    @Override
    public String addStockOutByTran(int id) {
        log.info("StockOutServiceImpl addStockOutByTran start transferId:" + id);
        //查询调拨订单
        StockTransfer stockTransfer = stockTransferMapper.selectStockTransferById(id);
        List<StockTransferDetail> list = stockTransferDetailMapper.getDetailByCode(stockTransfer.getTransferCode());
        StockOut stockOut = new StockOut();
        int number = 0;
        for (StockTransferDetail stockTransferDetail : list) {
            number += stockTransferDetail.getGoodsNum();
        }
        //给需求单对象赋值
        String stockOutCode = "CKXQ" + System.currentTimeMillis() + "";
        stockOut.setStockOutCode(stockOutCode);
        stockOut.setOrderCode(stockTransfer.getTransferCode());
        stockOut.setCreateBy(SecurityUtils.getUsername());
        stockOut.setInventoryTypeId(5);
        stockOut.setStockNum(number);
        stockOut.setHouseId(stockTransfer.getHouseOutId());
        //添加需求单
        int count = stockOutMapper.insertStockOut(stockOut);
        if (count < 0) {
            throw new ServiceException("系统错误 添加失败");
        }
        stockOut = stockOutMapper.getStockOutByCode(stockOutCode);
        for (StockTransferDetail stockTransferDetail : list) {
            StockOutDetail stockOutDetail = new StockOutDetail();
            stockOutDetail.setStockOutId(stockOut.getId());
            stockOutDetail.setGoodsId(stockTransferDetail.getGoodsId());
            stockOutDetail.setNum(stockTransferDetail.getGoodsNum());
            stockOutDetail.setCreateBy(SecurityUtils.getUsername());
            int count1 = stockOutDetailMapper.addDetail(stockOutDetail);
            if (count1 < 0) {
                throw new ServiceException("系统错误 添加失败");
            }
        }
        stockTransfer.setStatus(1);
        int count2 = stockTransferMapper.updateStockTransfer(stockTransfer);
        return "添加成功";
    }

    @Override
    public String addStockOutByBuyBack(BuyBackOrder buyBackOrder) {
        //查询销售订单
        StockOut stockOut = new StockOut();
        //给需求单对象赋值
        String stockOutCode = "CKXQ" + System.currentTimeMillis() + "";
        stockOut.setStockOutCode(stockOutCode);
        stockOut.setOrderCode(buyBackOrder.getBuyBackOrderCode());
        stockOut.setCreateBy(SecurityUtils.getUsername());
        stockOut.setInventoryTypeId(3);
        stockOut.setStockNum(buyBackOrder.getAllOutStock());
        stockOut.setCusName(buyBackOrder.getSupplier().getSupName());
        //添加需求单
        int count = stockOutMapper.insertStockOut(stockOut);
        if (count < 0) {
            throw new ServiceException("系统错误 添加失败");
        }
        BuyBackOrder buyBackOrder1 = new BuyBackOrder();
        buyBackOrder1.setIsStockOut(1);
        buyBackOrder1.setBuyBackOrderCode(buyBackOrder.getBuyBackOrderCode());
        AjaxResult ajaxResult = remoteBuyBackOrderService.updateBuyBackOrderByOrderCode(buyBackOrder1);
        stockOut = stockOutMapper.getStockOutByCode(stockOutCode);
        for (BuyBackOrderDetail backOrderDetail : buyBackOrder.getBuyBackOrderDetailList()) {
            StockOutDetail stockOutDetail = new StockOutDetail();
            stockOutDetail.setStockOutId(stockOut.getId());
            stockOutDetail.setGoodsId(backOrderDetail.getGoodsId());
            stockOutDetail.setNum(backOrderDetail.getOutStock());
            stockOutDetail.setCreateBy(SecurityUtils.getUsername());
            int count1 = stockOutDetailMapper.addDetail(stockOutDetail);
            if (count1 < 0) {
                throw new ServiceException("系统错误 添加失败");
            }
        }
        return "添加成功";
    }

    /**
     * 新增出库记录
     *
     * @param stockOut 出库记录
     * @return 结果
     */
    @Override
    public int insertStockOut(StockOut stockOut) {
        return stockOutMapper.insertStockOut(stockOut);
    }

    /**
     * 修改出库记录
     *
     * @param stockOut 出库记录
     * @return 结果
     */
    @Override
    public int updateStockOut(StockOut stockOut) {
        return stockOutMapper.updateStockOut(stockOut);
    }

    /**
     * 批量删除出库记录
     *
     * @param ids 需要删除的出库记录主键
     * @return 结果
     */
    @Override
    public int deleteStockOutByIds(Integer[] ids) {
        return stockOutMapper.deleteStockOutByIds(ids);
    }

    /**
     * 删除出库记录信息
     *
     * @param id 出库记录主键
     * @return 结果
     */
    @Override
    public int deleteStockOutById(Integer id) {
        return stockOutMapper.deleteStockOutById(id);
    }

    public List<StockOut> listForReciveOrder(StockOut stockOut) {
        List<StockOut> stockOutList = new ArrayList<>();
        if (stockOut.getInventoryTypeId() == 3) {
            stockOutList = stockOutMapper.selectStockOutListForBuyBackReciveOrder(stockOut);
        }
        if (stockOut.getInventoryTypeId() == 2) {
            stockOutList = stockOutMapper.selectStockOutListForSaleReciveOrder(stockOut);
        }
        for (StockOut stockOutParam : stockOutList) {
            stockOutParam.setReqNoMoney(stockOutParam.getReqMoney().subtract(stockOutParam.getReqVerMoney()));
        }

        return stockOutList;
    }

    public StockOut selectStockOutByStockOutCode(String stockOutCode) {
        return stockOutMapper.getStockOutByCode(stockOutCode);
    }
}
